#sms module
#!/usr/bin/python
#Filename: sms.py

import logging
import string
import icoach
import time

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.api import mail
from google.appengine.ext import db
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from datetime import datetime, timedelta, date
    
## HELPER METHODS ##
def lstSntThsRmndr(rmndr):
    '''Retrieve time and date specific message last sent'''    
    #try:                            
    previous = rmndr.date_sent
    if previous == None:
        return None
    else:
        elapsed_time = datetime.utcnow() - previous           
        return elapsed_time
    #except:
    #    return None
    
def send(r):
    '''Helper method to send messages to users'''  
    subject = "iReminder"
    body = "Reminder to: " + r.title
    user =  icoach.getProfile(r.profile)
    
    number = user.phone_num
    if number == "None" or number == None:
        recipient = user.email
    else:
        append=""
        carrier = user.phone_car
        if carrier == "AT&T":
            append = "@txt.att.net"
        elif carrier == "Alltel":
            append = "@message.alltel.com"
        elif carrier == "T-Mobile":
            append = "@sms.t-mobile.at"
        elif carrier == "Verizon":
            append = "@vtext.com"
        elif carrier == "Virgin Mobile":
            append = "@vmobl.com"
        elif carrier == "Suncom":
            append = "@tms.suncom.com"
        elif carrier == "Sprint (PCS)":
            append = "@messaging.sprintpcs.com"
        elif carrier == "Sprint (Nextel)":
            append = "@page.nextel.com"   
        elif carrier == "Cingular GoPhone":
            append = "@cingularme.com"                                                                      
                            
        number = user.phone_num.replace("-","")
        number = number.replace(" ","")
        recipient = number + append
    
    #sender should be sms@ireminder.net      
    message = mail.EmailMessage(sender = 'magellanscholar@gmail.com',to = recipient, subject = subject, body = body)      
    message.send()
    logging.info('Sent Reminder to %s @ %s' % (user.account, recipient))      
    logging.debug('Finish sending message to user')                                                                                                                                                                                                                                                                   

## REQUEST HANDLER ##                               
class SMS(webapp.RequestHandler):
    '''Sends reminders to users'''            
    def get(self):
        logging.debug('Beginning SMS Service')
        
        #try:      
        reminders = icoach.Reminders.all()
        
        for r in reminders:
            #time and date constants                        
            elapsed_time = lstSntThsRmndr(r)        
            strt_date = r.starts; end_date = r.ends                        
            userProfile = icoach.getProfile(r.profile)                     
                  
            #TIME MANIPULATIONS           
            rmndr_hour = r.time.find(":"); rmndr_hour = r.time[0:rmndr_hour]; rmndr_hour = int(rmndr_hour)                             
            rmndr_min = r.time.find(":"); rmndr_min = r.time[(rmndr_min+1):(rmndr_min+3)]; rmndr_min = int(rmndr_min)
            
            #convert standard time to military time             
            rmndr_time = r.time.replace(" ","")
            rmndr_time = rmndr_time.upper()
            mrdm = rmndr_time.find("M")
            mrdm = rmndr_time[(mrdm-1):]            
            if mrdm == "PM": rmndr_hour = rmndr_hour + 12                                                                        
            
            #format time zone                      
            tmz = userProfile.tmz
            tmz_hour = tmz.find(":")
            tmz_min = tmz[(tmz_hour):]
            tmz_hour = tmz[0:(tmz_hour-1)]            
            if tmz_min == ".5":
                tmz_min = "30"
            elif tmz_min ==".75":
                tmz_min = "45"
            tmz_hour = int(tmz_hour)
            tmz_min = int(tmz_min)
                        
            cur_hour = datetime.now().hour; cur_min = datetime.now().minute 
                                    
            cur_time = timedelta(minutes=cur_min, hours=cur_hour)
            tmz_time = timedelta(minutes=tmz_min, hours=tmz_hour)
            rmndr_time = timedelta(minutes=rmndr_min, hours=rmndr_hour)
            
            #adjust gmt time to timezone
            cur_time = cur_time + tmz_time        
            
            #DATE MANIPULATIONS
            strt_month = strt_date[0:2]; strt_day = strt_date[3:5]; strt_year = strt_date[6:];
            end_month = end_date[0:2]; end_day = end_date[3:5]; end_year = end_date[6:]; 
                        
            strt_date = datetime(int(strt_year),int(strt_month),int(strt_day),rmndr_hour,rmndr_min,0)
            end_date = datetime(int(end_year),int(end_month),int(end_day),11,59,59)                                           
            cur_date = datetime(int(datetime.now().year),int(datetime.now().month),int(datetime.now().day),int(cur_hour),int(cur_min),int(datetime.now().second))  
            
            #Algorithm to determine when to send reminders
            if r.repeats == "Once":                
                if (cur_date.date() >= strt_date.date()) and (cur_date.date() <= end_date.date()) and (r.date_sent == None):
                    logging.info('Loop Once: A') 
                    logging.info('cur_hour: %s, hour: %s' % (cur_hour, hour))
                    logging.info('cur_min: %s, min: %s' % (cur_min, min))
                    logging.info('time: %s' % datetime.now()) 
                    logging.info('time: %s' % datetime.utcnow()) 
                    logging.info('time: %s' % time.localtime())                                                                 
                    if cur_time == rmndr_time:
                        logging.info('Loop Once: B')  
                        #This is if the mailing service times out by Google. Then we send the next cron job
                        #or ((int(cur_hour) == int(hour)) and (int(cur_min) == (int(min)+1)))
                        r.date_sent = cur_date
                        send(r)                      
                                                              
            elif r.repeats == "Daily":
                logging.debug('elapsed time: %s' % elapsed_time)
                if (cur_date.date() >= strt_date.date()) and (cur_date.date() <= end_date.date()) and ((elapsed_time == None) or (elapsed_time >= timedelta(days = 1))):                                                                    
                    if cur_time == rmndr_time:
                        #This is if the mailing service times out by Google. Then we send the next cron job
                        #or ((int(cur_hour) == int(hour)) and (int(cur_min) == (int(min)+1)))
                        r.date_sent = cur_date
                        send(r)                   
                            
            elif r.repeats == "Weekly":
                if (cur_date.date() >= strt_date.date()) and (cur_date.date() <= end_date.date()) and ((elapsed_time == None) or (elapsed_time >= timedelta(days = 7))):                                                                    
                    if cur_time == rmndr_time:
                        #This is if the mailing service times out by Google. Then we send the next cron job
                        #or ((int(cur_hour) == int(hour)) and (int(cur_min) == (int(min)+1)))
                        r.date_sent = cur_date
                        send(r)                  
                
            elif r.repeats == "Yearly":
                if (cur_date.date() >= strt_date.date()) and (cur_date.date() <= end_date.date()) and ((elapsed_time == None) or (elapsed_time >= timedelta(days = 375))):                                                                    
                    if cur_time == rmndr_time:
                        #This is if the mailing service times out by Google. Then we send the next cron job
                        #or ((int(cur_hour) == int(hour)) and (int(cur_min) == (int(min)+1)))
                        r.date_sent = cur_date
                        send(r)                                  
            else:                
                logging.debug('No reminders in database; Someone manipulated javascript to different "repeats"')
                
        #except:                                                                              
        logging.debug('Ending SMS Service')       
                
application = webapp.WSGIApplication(
                                     [('/sms/messages', SMS)],
                                     debug=True)
  
def main():
    logging.getLogger().setLevel(logging.DEBUG)
    run_wsgi_app(application)

if __name__ == "__main__":
    main()